package ua.com.abakumov.android.prostopleer.tasks

import java.io._
import android.util.Log
import android.os.{Environment, StrictMode}
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.client.methods.HttpPost
import org.apache.http.HttpStatus
import util.parsing.json.JSON
import java.net.{URISyntaxException, URI}
import org.apache.http.client.utils.URIUtils
import ua.com.abakumov.android.prostopleer.util.Composition

/**
 * DownloadTask
 *
 * @author alexander-abakumov
 *         Date: 24.10.12
 */
class DownloadTask(
                    protocol : String,
                    host : String,
                    downloadPath : String,
                    downloadQuery : String,
                    done: Done[String]) extends AsyncTaskWithCallback[Object, String, String](done) {


  protected override def onProgressUpdate(values: String*) {
    Log.i("Download task says:", values.toString())
  }

  private def extractHttpLink(json: String): String = {
    JSON.parseFull(json) match {
      case Some(o) => {
        val map = o.asInstanceOf[Map[String, Any]]
        map("track_link").asInstanceOf[String]
      }
      case None => ""
      case _ => ""
    }
  }

  private def createDownloadURI(link: String): URI = {
    var uri: URI = null

    try {
      uri = URIUtils.createURI(
        protocol,
        host,
        -1,
        downloadPath,
        downloadQuery + link, null)
    }
    catch {
      case (e: URISyntaxException) => e.printStackTrace()
    }

    uri
  }

  private def save(from: InputStream, to: FileOutputStream) {

    var bufferReadLength: Int = 0
    val rwBuffer: Array[Byte] = new Array[Byte](1024)
    var readBytes: Int = 0

    while ( {
      bufferReadLength = from.read(rwBuffer)
      bufferReadLength > 0
    }) {
      to.write(rwBuffer, 0, bufferReadLength)
      readBytes = readBytes + bufferReadLength

      publishProgress(readBytes.toString)
    }
  }

  private def isCardAvailable = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState)

  protected override def doInBackground(params: Object*): String = {
    val composition = params(0).asInstanceOf[Composition]
    val downloadURI = createDownloadURI(composition.link)

    Log.i("Song download URI is ", downloadURI.toString)


    val jsonDownloadFileInformationResponse = new DefaultHttpClient().execute(new HttpPost(downloadURI))

    jsonDownloadFileInformationResponse.getStatusLine.getStatusCode match {
      // OK status
      case (HttpStatus.SC_OK) => {
        val out = new ByteArrayOutputStream
        jsonDownloadFileInformationResponse.getEntity.writeTo(out)

        val responseFile = new DefaultHttpClient().execute(new HttpPost(extractHttpLink(out.toString)))

        responseFile.getStatusLine.getStatusCode match {

          // OK
          case (HttpStatus.SC_OK) => {

            val fileNameSaved: String = isCardAvailable match {
              case true => {
                val fileName: String = composition.artist + composition.song + ".mp3"
                val from: InputStream = responseFile.getEntity.getContent
                val directoryTo: File = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                val to: FileOutputStream = new FileOutputStream(new File(directoryTo, fileName))
                save(from, to)
                fileName
              }
              //mountCardErrorListener() TODO : ?
              case _ => ""
            }

            fileNameSaved
          }
          // ???
          case _ => ""
        }
      }
      // ???
      case _ => ""
    }
  }
}